package com.hgyc.mom.mes.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hgyc.mom.base.entity.BomItem;
import com.hgyc.mom.base.service.BomItemService;
import com.hgyc.mom.common.exception.BizException;
import com.hgyc.mom.mes.entity.MesWorkOrder;
import com.hgyc.mom.mes.entity.MesWorkOrderBomItem;
import com.hgyc.mom.mes.entity.MesWorkOrderBomSubstitute;
import com.hgyc.mom.mes.entity.MesWorkOrderProcess;
import com.hgyc.mom.mes.enums.WorkOrderStatusEnum;
import com.hgyc.mom.mes.mapper.MesWorkOrderMapper;
import com.hgyc.mom.mes.service.MesWorkOrderBomItemService;
import com.hgyc.mom.mes.service.MesWorkOrderBomSubstituteService;
import com.hgyc.mom.mes.service.MesWorkOrderProcessService;
import com.hgyc.mom.mes.service.MesWorkOrderService;
import com.hgyc.mom.mes.vo.MesWorkOrderVO;
import com.hgyc.mom.tool.strategy.AutoCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * 生产工单Service业务层实现
 *
 * @author fwj
 * @since 2025-07-10
 */
@Slf4j
@Service
public class MesWorkOrderServiceImpl extends ServiceImpl<MesWorkOrderMapper, MesWorkOrder> implements MesWorkOrderService {

    @Autowired
    private MesWorkOrderBomItemService mesWorkOrderBomItemService;
    @Autowired
    private MesWorkOrderBomSubstituteService mesWorkOrderBomSubstituteService;
    @Autowired
    private MesWorkOrderProcessService mesWorkOrderProcessService;

    @Autowired
    private AutoCodeUtil autoCodeUtil;
    @Autowired
    private BomItemService bomItemService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(MesWorkOrderVO mesWorkOrderVO) {
        String workOrderCode = autoCodeUtil.genSerialCode("WORK_ORDER_CODE", null);
        mesWorkOrderVO.setWorkOrderCode(workOrderCode);

        save(mesWorkOrderVO);

        //新增生产工单BOM组成
        List<MesWorkOrderBomItem> items = mesWorkOrderVO.getAddItems();
        if (!CollectionUtils.isEmpty(items)) {
            items.forEach(item -> {
                item.setId(null);
                item.setWorkOrderId(mesWorkOrderVO.getId());
            });
            mesWorkOrderBomItemService.saveBatch(items);
        }
        //新增工单替代料
        List<MesWorkOrderBomSubstitute> substitutes = mesWorkOrderVO.getAddSubstitutes();
        if (!CollectionUtils.isEmpty(substitutes)) {
            substitutes.forEach(item -> {
                item.setId(null);
                item.setWorkOrderId(mesWorkOrderVO.getId());
            });
            mesWorkOrderBomSubstituteService.saveBatch(substitutes);
        }
        //新增工单工艺路线
        List<MesWorkOrderProcess> processList = mesWorkOrderVO.getAddProcessList();
        if (!CollectionUtils.isEmpty(processList)) {
            processList.forEach(item -> {
                item.setId(null);
                item.setWorkOrderId(mesWorkOrderVO.getId());
            });
            mesWorkOrderProcessService.saveBatch(processList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrder(MesWorkOrderVO mesWorkOrderVO) {
        // TODO 其他逻辑
        updateById(mesWorkOrderVO);

        //删除生产工单BOM组成
        if (!CollectionUtils.isEmpty(mesWorkOrderVO.getDeleteItemIds())) {
            mesWorkOrderBomItemService.removeBatchByIds(mesWorkOrderVO.getDeleteItemIds());
        }

        //新增生产工单BOM组成
        List<MesWorkOrderBomItem> items = mesWorkOrderVO.getAddItems();
        if (!CollectionUtils.isEmpty(items)) {
            items.forEach(item -> {
                item.setId(null);
                item.setWorkOrderId(mesWorkOrderVO.getId());
            });
            mesWorkOrderBomItemService.saveBatch(items);
        }

        //更新生产工单BOM组成
        if (!CollectionUtils.isEmpty(mesWorkOrderVO.getUpdateItems())) {
            List<MesWorkOrderBomItem> updateItems = mesWorkOrderVO.getUpdateItems();
            mesWorkOrderBomItemService.updateBatchById(updateItems);
        }
        //删除工单替代料
        if (!CollectionUtils.isEmpty(mesWorkOrderVO.getDeleteSubstituteIds())) {
            mesWorkOrderBomSubstituteService.removeBatchByIds(mesWorkOrderVO.getDeleteSubstituteIds());
        }

        //新增工单替代料
        List<MesWorkOrderBomSubstitute> substitutes = mesWorkOrderVO.getAddSubstitutes();
        if (!CollectionUtils.isEmpty(substitutes)) {
            substitutes.forEach(item -> {
                item.setId(null);
                item.setWorkOrderId(mesWorkOrderVO.getId());
            });
            mesWorkOrderBomSubstituteService.saveBatch(substitutes);
        }

        //更新工单替代料
        if (!CollectionUtils.isEmpty(mesWorkOrderVO.getUpdateSubstitutes())) {
            List<MesWorkOrderBomSubstitute> updateSubstitutes = mesWorkOrderVO.getUpdateSubstitutes();
            mesWorkOrderBomSubstituteService.updateBatchById(updateSubstitutes);
        }
        //删除工单工艺路线
        if (!CollectionUtils.isEmpty(mesWorkOrderVO.getDeleteProcessIds())) {
            mesWorkOrderProcessService.removeBatchByIds(mesWorkOrderVO.getDeleteProcessIds());
        }

        //新增工单工艺路线
        List<MesWorkOrderProcess> processList = mesWorkOrderVO.getAddProcessList();
        if (!CollectionUtils.isEmpty(processList)) {
            processList.forEach(item -> {
                item.setId(null);
                item.setWorkOrderId(mesWorkOrderVO.getId());
            });
            mesWorkOrderProcessService.saveBatch(processList);
        }

        //更新工单工艺路线
        if (!CollectionUtils.isEmpty(mesWorkOrderVO.getUpdateProcessList())) {
            List<MesWorkOrderProcess> updateProcessList = mesWorkOrderVO.getUpdateProcessList();
            mesWorkOrderProcessService.updateBatchById(updateProcessList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeOrder(List<Long> ids) {
        // TODO 其他逻辑
        removeByIds(ids);
        //删除生产工单BOM组成
        mesWorkOrderBomItemService.deleteBatchByParentIds(ids);
        //删除工单替代料
        mesWorkOrderBomSubstituteService.deleteBatchByParentIds(ids);
        //删除工单工艺路线
        mesWorkOrderProcessService.deleteBatchByParentIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void split(Long id, Integer splitQty) {
        MesWorkOrder workOrder = getById(id);

        BigDecimal newPlayQty = workOrder.getPlanQty().subtract(new BigDecimal(splitQty));
        // 1. 更新计划数
        workOrder.setPlanQty(newPlayQty);
        updateById(workOrder);

        // 2. 更新bom
        List<MesWorkOrderBomItem> bomItemList = mesWorkOrderBomItemService.getByParentId(id);
        for (MesWorkOrderBomItem bomItem : bomItemList) {
            BigDecimal hundred = new BigDecimal("100");
            BigDecimal lossMultiplier = BigDecimal.ONE.add(bomItem.getLossRate().divide(hundred, 4, RoundingMode.HALF_UP));
            bomItem.setTotalQty(newPlayQty.multiply(bomItem.getQty()).multiply(lossMultiplier));
        }
        mesWorkOrderBomItemService.updateBatchById(bomItemList);

        // 新增新的工单
        List<MesWorkOrder> splitWorkOrderList = getSplitWorkOrderList(id);
        String splitWorkOrderCode = workOrder.getWorkOrderCode();
        if (CollectionUtils.isEmpty(splitWorkOrderList)) {
            splitWorkOrderCode = splitWorkOrderCode + "-1";
        } else {
            splitWorkOrderCode = splitWorkOrderCode + "-" + (splitWorkOrderList.size() + 1);
        }

        MesWorkOrder splitWorkOrder = new MesWorkOrder();
        BeanUtils.copyProperties(workOrder, splitWorkOrder);
        splitWorkOrder.setId(null);
        splitWorkOrder.setWorkOrderCode(splitWorkOrderCode);
        splitWorkOrder.setParentId(workOrder.getId());
        splitWorkOrder.setStatus(WorkOrderStatusEnum.PREPARE.getValue());
        splitWorkOrder.setPlanQty(new BigDecimal(splitQty));
        splitWorkOrder.setActualQty(BigDecimal.ZERO);
        splitWorkOrder.setQuantityScheduled(BigDecimal.ZERO);
        splitWorkOrder.setProgress(BigDecimal.ZERO);
        splitWorkOrder.setScrapQty(BigDecimal.ZERO);
        splitWorkOrder.setReworkQty(BigDecimal.ZERO);
        save(splitWorkOrder);

        //bom信息
        List<MesWorkOrderBomItem> splitBomItemList = new ArrayList<>();
        for (MesWorkOrderBomItem bomItem : bomItemList) {
            MesWorkOrderBomItem splitItem = new MesWorkOrderBomItem();
            BeanUtils.copyProperties(bomItem, splitItem);
            splitItem.setId(null);
            splitItem.setWorkOrderId(splitWorkOrder.getId());

            BigDecimal hundred = new BigDecimal("100");
            BigDecimal lossMultiplier = BigDecimal.ONE.add(bomItem.getLossRate().divide(hundred, 4, RoundingMode.HALF_UP));
            splitItem.setTotalQty(new BigDecimal(splitQty).multiply(bomItem.getQty()).multiply(lossMultiplier));

            splitBomItemList.add(splitItem);
        }
        mesWorkOrderBomItemService.saveBatch(splitBomItemList);

        //替代料
        List<MesWorkOrderBomSubstitute> substituteList = mesWorkOrderBomSubstituteService.getByParentId(id);
        List<MesWorkOrderBomSubstitute> splitSubstituteList = new ArrayList<>();
        for (MesWorkOrderBomSubstitute bomSubstitute : substituteList) {
            MesWorkOrderBomSubstitute splitSubstitute = new MesWorkOrderBomSubstitute();
            BeanUtils.copyProperties(bomSubstitute, splitSubstitute);
            splitSubstitute.setId(null);
            splitSubstitute.setWorkOrderId(splitWorkOrder.getId());
            splitSubstituteList.add(splitSubstitute);
        }
        mesWorkOrderBomSubstituteService.saveBatch(splitSubstituteList);

        //工序
        List<MesWorkOrderProcess> processList = mesWorkOrderProcessService.getByParentId(id);
        List<MesWorkOrderProcess> splitProcessList = new ArrayList<>();
        for (MesWorkOrderProcess process : processList) {
            MesWorkOrderProcess splitProcess = new MesWorkOrderProcess();
            BeanUtils.copyProperties(process, splitProcess);
            splitProcess.setId(null);
            splitProcess.setWorkOrderId(splitWorkOrder.getId());
            splitProcessList.add(splitProcess);
        }
        mesWorkOrderProcessService.saveBatch(splitProcessList);
    }

    /**
     * 获取工单拆分的工单
     * @param workOrderId 工单ID
     * @return 拆分工单
     */
    private List<MesWorkOrder> getSplitWorkOrderList(Long workOrderId) {
        LambdaQueryWrapper<MesWorkOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MesWorkOrder::getParentId, workOrderId);
        return list(queryWrapper);
    }

    @Override
    public void transmit(MesWorkOrder mesWorkOrder) {
        mesWorkOrder.setStatus(WorkOrderStatusEnum.RELEASED.getValue());
        updateById(mesWorkOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importData(List<MesWorkOrder> mesWorkOrderList, boolean updateSupport) {
        if (mesWorkOrderList == null || mesWorkOrderList.isEmpty()) {
            throw new IllegalArgumentException("导入数据不能为空");
        }

        try {
            if (updateSupport) {
                // TODO 实现更新已有数据的导入逻辑
                return "更新导入成功，共导入 " + mesWorkOrderList.size() + " 条数据";
            } else {
                // TODO 实现不更新已有数据的导入逻辑
                return "新增导入成功，共导入 " + mesWorkOrderList.size() + " 条数据";
            }
        } catch (Exception e) {
            log.error("生产工单导入失败", e);
            throw new BizException("生产工单导入失败：" + e.getMessage());
        }
    }
}